<?php

namespace App\Services\SwitchPay;

use App\Caches\YibaoWxH5PayCreateCache;
use App\Commons\CommonConstant;
use App\Models\Orders;
use App\Services\PayMchService;
use App\Services\QrCodeService;
use Illuminate\Http\Request;
use YQ\YqExtend;
use Illuminate\Support\Facades\Http;

/**
 * 易包聚合-微信H5
 */
class YibaoWxH5 extends SwitchPayBase
{
    private function createPaySign($params, $paykey)
    {
        $arr = [];
        ksort($params);
        foreach ($params as $key => $val) {
            if ($key === 'sign') continue;
            if ($val === '' || $val === 'null' || $val === 'undefined' || is_null($val)) continue;
            $arr[] = "$key=$val";
        }
        $str  = implode("&", $arr) . "&paySecret={$paykey}";
        $sign = strtoupper(md5($str));

        return $sign;
    }

    private function getYibaoPayConfig()
    {
        $ybpay_name = $this->gameChannel['yibao_pay'];
        $config = PayMchService::getInstance()->getByName($ybpay_name);
        return $config;
    }

    // 创建订单初始化-微信二维码支付
    private function payInitToQrcode($url)
    {
        $qrcode_file = QrCodeService::getInstance()->createQrcodeAndJumpUrl($url);
        $qrcode_url = config('app.url') . '/' . ltrim(strstr($qrcode_file, '/uploads'), '/');

        return $qrcode_url;
    }

    // 创建订单
    public function payInit(Orders $order, Request $request)
    {
        $trade_no = $order->trade_no;
        $cache = YibaoWxH5PayCreateCache::getInstance()->get($trade_no);
        if (!empty($cache)) {
            return yqok($cache);
        }

        $config = $this->getYibaoPayConfig();

        $goods_name = str_replace('+', '-', $order->goods_name);
        $params = [
            'tradeType'  => 'cs.pay.submit',
            'version'    => '2.0',
            'channel'    => 'wx_h5',
            'mchNo'      => $config['mch_id'],   // 本平台下发的商户号
            'body'       => $goods_name,
            'mchOrderNo' => $order->trade_no,
            'amount'     => strval($order->money * 100),
            'currency'   => 'CNY',
            'timePaid'   => date('YmdHis', time()),
            'remark' => $goods_name,
        ];

        $extra = [
            'notifyUrl' => $this->callbackUrl(),
            'callbackUrl' => $this->payCompleteUrl($order),
            'clientIp' => YqExtend::getIP(),
        ];

        $sign_data = array_merge($params, $extra);
        $params['sign'] = $this->createPaySign($sign_data, $config['mch_key']);
        $params['extra'] = json_encode($extra);

        $url = 'http://game.quzhilian.net/gateway/api/trade';
        $response = Http::asForm()->post($url, $params);
        if (!$response->ok()) {
            yqlog($url, $params, $response->body());
            return yqerr(6032);
        }

        $res = json_decode($response->body(), true);
        if ($res['resultCode'] != '0') {
            yqlog($url, $params, $response->body());
            return yqerr(6033);
        }

        $res['jump_qrcode_url'] = QrCodeService::getInstance()->getJumpQrcodeUrl($res['message']);
        YibaoWxH5PayCreateCache::getInstance()->update($trade_no, $res);

        return yqok($res);
    }

    // 支付回调
    public function payCb(Request $request, $cb_type)
    {
        $notify = $this->payNotify;
        $notify->cbType = $cb_type;

        $params = $request->all();
        $config = $this->getYibaoPayConfig();

        // 校验签名
        $sign = $this->createPaySign($params, $config['mch_key']);
        if ($sign != $params['sign']) {
            $notify->errno = 101;
            return $notify;
        }

        // 支付接口 0为支付成功
        if ($params['payResult'] != '0') {
            $notify->errno = 6034;
            return $notify;
        }

        // 校验商户号
        if ($params['mchNo'] != $config['mch_id']) {
            $notify->errno = 6034;
            return $notify;
        }

        // 校验订单
        $trade_no = $params['mchOrderNo'];
        $order = Orders::where('trade_no', $trade_no)->first();
        if (!$order) {
            $notify->errno = 6020;
            return $notify;
        }

        // 校验充值金额
        if (abs($order->money - $params['amount'] / 100) > 1) {
            $notify->errno = 6024;
            return $notify;
        }

        $notify->order          = $order;
        $notify->tradeNo        = $trade_no;
        $notify->channelTradeNo = $params['cpOrderNo'];
        $notify->mchId          = $config['mch_id'];

        return $notify;
    }

    // 失败返回
    public function payErr()
    {
        $notify = $this->payNotify;
        return $notify->errno;
    }

    // 成功返回
    public function payOk()
    {
        return 'success';
    }
}
